home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 20
/
Cream of the Crop 20 (Terry Blount) (1996).iso
/
editor
/
numlines.zip
/
NUMLINES.ASM
< prev
next >
Wrap
Assembly Source File
|
1996-06-20
|
5KB
|
164 lines
; NumLines Barry Block v5 6-96 assemble with A86
.Radix 16
buffer_size equ 0F400h ;buffer size = 61k
o equ offset
Org 100h
Jmp start
Db 1bh,5bh,32h,4ah,0dh
brag Db 'NumLines v5 by Barry Block 6-96 2:820/901.42'
Db 0Dh,0Ah,24h,0dh
usage Db 'Counts number of lines in a textfile.',0dh,0ah
Db 'Faster than 4DOS function, @lines[filename]',0dh,0ah
Db 'Usage: Numlines Filename',0dh,0ah
Db 9,'Numlines Filename|input %%var',0dh,0ah
Db 24h,0dh,20h,0dh,1ah
;---------------------------------------
start: Call init
Call open_file
_Do: Call read_file
Call filter
Call status
Jmp short _Do
;---------------------------------------
init: Mov si,82h ;check CommandTail for filename
Cmp b[si],0h ;is it zero?
Jz err_use ;commandtail wrong
loop1: Lodsb
Cmp al,0Dh
Jnz loop1
Mov w[si-1],0 ;replace CR (13) with 0 in the filename
Ret
err_use: Mov b set_err,-1 ;no filename?
Jmp short _q ;clear ret off stack and quit
;---------------------------------------
open_file: Mov dx,82h ;point dx to filename
Mov ax,3d00h ;DOS:open file, DS:DX=name
Int 21h ; AL=access code, 0 is read only
Jc o_err ; AX=error code if carry set
Mov handle,ax ;AX holds Handle
Ret
o_err: Mov b set_err,-1
_q: pop ax
Jmp short quit
;---------------------------------------
read_file: Clc
Mov bx,handle ;DOS:move file ptr,
Xor dx,Dx ; AL=method BX=hnd
Mov ax,4201h ;CX:DX = #bytes,ret DX:AX=pos in file
Mov cx,0
Int 21h
Mov FilePtrH,Dx ;Store current position
Mov FilePtrL,Ax
Mov dx,o buffer
Mov cx,buffer_size ;DOS:read file, BX=handle
Mov ah,3fh ; CX=# bytes,DS:DX=buffer
Int 21h ; addr,ret AX=err code if carry
Mov NumBytes,Ax
Jc ReadErr
Cmp ax,cx
Je RFDone
SetEOF: Mov b EOF,-1
Jmp short RFDone
ReadErr: Cmp ax,0
Je SetEOF ;no problem
Mov set_err,-1 ;yes, read error
Jmp short status
RFDone: Ret
;---------------------------------------
filter: Mov cx,NumBytes
Cmp cx,0
If z mov set_err,-1
Mov si,o buffer
Inc cx ;al is one behind si. get last byte
proc_l: Lodsb
Cmp al,0ah ;0ah is linefeed, so another line
Jne _loopl
Inc w line_count_l ;lines found
Cmp line_count_l,0 ;may be 0FFFF+1 lines
If z inc w line_count_h ; so inc high byte
_loopl: Loop proc_l
Or ax,ax ;reset flags
Ret
;---------------------------------------
status: Jc close_file ;keep loading buffer till EOF
Cmp b EOF,-1
Jne ret
;---------------------------------------
close_file: Pop ax ;take ret off of stack
Mov ah,3eh ;DOS:close file, BX=handle
Mov bx,handle
Int 21h ; returns AX=error code
;---------------------------------------
quit: Cmp set_err,0
Je normal ;no error
Mov dx,o err_level
Mov ah,9 ;display -1 error
Int 21h
crlf: Mov dx,o nwln ;send cr,lf
Mov ah,9
Int 21h
exit: Mov ah,4ch
Mov al,set_err
Int 21h ;exit w/errorlevel
normal: Call dec_32 ;display number of lines
Jmp short crlf
;---------------------------------------
dec_32: Mov bx,line_count_h
Cmp bx,0 ;won't be zero if even 1 line (char10)
Je no_line
Dec bx ;first one don't count
Mov ax,line_count_l
Jmp short DNUMP
no_line: Mov ax,0 ;no lines, but display "0"
;-------------------------------------------------------------;
; Richard Pavlicek <pavlicek@gate.net> ;
; ;
;Below is my routine, which displays (in decimal) the 32-bit ;
;number in bx:ax. For a 16-bit number, simply set bx to zero.;
;-------------------------------------------------------------;
; Display number | bx high word, ax low word ;
;-------------------------------------------------------------;
DNUMP: mov cx,0ah ;divisor and flag
push cx ;put flag on stack
;- divide & store digit loop
DNUM1: xchg ax,bx ;make ax high word, bx low word
sub dx,dx ;extend high word
div cx ;dx = remainder, ax high quotient
xchg ax,bx ;save high quotient, get low word
div cx ;dx = digit (0-9), ax low quotient
push dx ;save digit (remainder) on stack
mov dx,bx ;copy so not destroyed below
or dx,ax ;is full quotient zero?
jnz DNUM1 ;no, continue
pop dx ;get most significant digit
;- display loop
DNUM2: or dl,30h ;convert to ASCII digit
mov ah,02h ;DOS display character function
int 21h ;display it
pop dx ;get next digit or flag
cmp dx,cx ;is it a digit (less than 10)?
jc DNUM2 ;yes, continue display
ret ;no, flag met (stack normal)
;-------------------------------------------------------------;
FilePtrH Dw 0
FilePtrL Dw 0
NumBytes Dw 0
handle Dw 0
line_count_l Dw 0ffffh
line_count_h Dw 0
EOF Db 0
set_err Db 0
err_level Db '-1$'
nwln Db 0dh,0ah,24h
buffer Db